import 'dart:math';

import 'package:flutter/material.dart';

class SnowPage extends StatefulWidget {
  const SnowPage({Key? key}) : super(key: key);

  @override
  _SnowPageState createState() => _SnowPageState();
}

class _SnowPageState extends State<SnowPage>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;
  final List<SnowFlake> _listSnowFlakes =
      List.generate(1000, (index) => SnowFlake());

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    _controller =
        AnimationController(duration: Duration(seconds: 1), vsync: this)
          ..repeat();
  }

  @override
  void dispose() {
    _controller.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('堆雪人'),
      ),
      body: Container(
        width: double.infinity,
        height: double.infinity,
        decoration: const BoxDecoration(
          gradient: LinearGradient(
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              colors: [Colors.blue, Colors.lightBlue, Colors.white],
              stops: [0, 0.8, 0.95]),
        ),
        child: AnimatedBuilder(
            animation: _controller,
            builder: (context, _) {
              return CustomPaint(painter: MyPaint(_listSnowFlakes));
            }),
      ),
    );
  }
}

class MyPaint extends CustomPainter {
  MyPaint(this._listSnowFlakes);
  final List<SnowFlake> _listSnowFlakes;
  final Paint _paint = Paint()..color = Colors.white;

  @override
  void paint(Canvas canvas, Size size) {
    // print(size);
    canvas.drawCircle(size.center(Offset(0, 80)), 60, _paint);
    canvas.drawOval(
      Rect.fromCenter(
        center: size.center(Offset(0, 250)),
        width: 200,
        height: 250,
      ),
      _paint,
    );
    for (SnowFlake e in _listSnowFlakes) {
      e.fall();
      canvas.drawCircle(Offset(e.x, e.y), e.r, _paint);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

class SnowFlake {
  double x = Random().nextDouble() * 390;
  double y = Random().nextDouble() * 741;
  double r = Random().nextDouble() * 1 + 1;
  double speed = Random().nextDouble() * 4 + 1;

  fall() {
    if (y < 750) {
      y += speed;
    } else {
      y = 0;
      x = Random().nextDouble() * 390;
      r = Random().nextDouble() * 1 + 1;
    }
  }
}
